﻿/**
 * @file menu_key_process.c
 * @brief this is a brief description
 * @details this is the detail description.
 * @author fulong 
 * @data 7/31/2014
 * @version 1.0
 * @par Copyright (c):
 * @par First build
 *     version: fulong 
 *     data: 7/31/2014
 */
#include "menu_process.h"
#include "menu_common.h"
#include "../../hal/hal_key.h"
#ifndef __SIMPLE_DISPLAY__
    #include "../../hal/display.h"
#else
    #include "../../hal/hal_seven_seg_led.h"
#endif
#include "../../bsp/board.h"
#ifdef MENU_DEBUG
    #include "../../dev/uart.h"
#endif
#include "string.h"
#include "../../lib/delay.h"
#include "../../lib/libmath.h"

#ifdef MENU_ENABLE

extern hal_key_struct hal_key_proc;
extern inner_proc_struct inner_proc_var[MENU_MAX_COUNT];
extern menu_id_table_struct menu_widget_table;
extern menu_id_table_index_struct menu_widget_index;
extern menu_flag_struct menu_flag;
extern menu_struct cur_menu;
extern menu_struct pre_menu;
extern uint8 old_menu_num;
extern menu_controllable_strcut  menu_controllable;
static uint16 menu_get_widget_type(uint8 menu_widget_num);
void widget_display(void)
{
    static_text_widget_struct *static_txt;
    display_text_widget_struct *display_txt;
    menu_button_struct *button_tmp;
    uint8 var_array[6] = { '0', '0', '0', '0', '0', '0' };
    uint8 counter;
    uint32 delay_tmp = 0;
    uint16 menu_widget_type;
    uint8 menu_proc_type;
    uint8 menu_seg_proc_type;
    menu_widget_type = menu_get_widget_type(cur_menu.cur_dis_widget_num);
    menu_proc_type = (menu_widget_type)&0x01;
    menu_seg_proc_type = (menu_widget_type >> 8) & 0x3;
    if (menu_proc_type == WIDGET_TEXT)
    {
        switch (menu_seg_proc_type)
        {
            case STATIC_TEXT:
                if (!menu_flag.flag.static_txt_displayed)
                {
                    static_txt =  (static_text_widget_struct *)menu_widget_table.menu_table[cur_menu.cur_dis_widget_num];
                    hal_display_word(static_txt->static_text_x, static_txt->static_text_y, static_txt->static_text);
                }
                break;
            case SHIFT_TEXT:
                break;
            case DAS_TEXT:
                break;
            case DISPLAY_TEXT:
                display_txt =  (display_text_widget_struct *)menu_widget_table.menu_table[cur_menu.cur_dis_widget_num];
                apply4delay(MENU_DISPLAY_FLAG, MENU_DISPLAY_TIME);
                if (get_delay_flag(MENU_DISPLAY_FLAG))
                {
                    menu_flag.flag.display_txt_displayed = 0;
                }
                if (display_txt->flash_enable)
                {
                    apply4delay(display_txt->delay_flash_flag, MENU_FLASH_TIME);
                    if (get_delay_flag(display_txt->delay_flash_flag))
                    {
                        display_txt->display_clr_flag = !display_txt->display_clr_flag;
                        menu_flag.flag.display_txt_displayed = 0;
                    }
                }
                if (!menu_flag.flag.display_txt_displayed)
                {
                    if (display_txt->dis_type == MENU_DIS_VAR)
                    {
                        oct_transfer(display_txt->dis_var, var_array, 'd', 1);
                        display_txt->dis_txt = var_array;
                    }
                    if (display_txt->display_clr_flag)
                    {
                        hal_screen_clr_location(display_txt->dis_text_x, display_txt->dis_text_y, strlen((const char *)display_txt->dis_txt_old));
                    } else
                    {
                        if (strcmp((const char *)display_txt->dis_txt_old, (const char *)display_txt->dis_txt))
                        {
                            hal_screen_clr_location(display_txt->dis_text_x, display_txt->dis_text_y, strlen((const char *)display_txt->dis_txt_old));
                        }
                        hal_display_word(display_txt->dis_text_x, display_txt->dis_text_y,  display_txt->dis_txt);
                        display_txt->dis_txt_old = display_txt->dis_txt;
                    }
                }
                break;
            default:
                break;
        }
    } else if (menu_proc_type == WIDGET_BUTTON)
    {
        button_tmp = (menu_button_struct *)menu_widget_table.menu_table[cur_menu.cur_dis_widget_num];
        switch (menu_seg_proc_type)
        {
            case MENU_CONTINUE_BUTTON_PRESS:
                counter = 0;
                while (counter < hal_key_proc.hal_key_len)
                {
                    if (button_tmp->bind_key == hal_key_proc.hal_key_saved[counter] &&  hal_key_proc.hal_key_status[counter] == HAL_KEY_CONTINUE_PRESS_STATUS)
                    {
                        if (button_tmp->delay_button_time != 0)
                        {
                            delay_tmp = get_time_counter();
                        }
                        if (button_tmp->delay_button_node == WIDGET_BUTTON_DELAY_ENABLE &&  button_tmp->delay_button_time != 0)
                        {
                            button_tmp->delay_button_node = delay_tmp + button_tmp->delay_button_time;
                        }
                        if (delay_tmp >= button_tmp->delay_button_node)
                        {
                            button_tmp->menu_button_proc_fun();
                            //删除已经处理过的键值
                            update_key_value(counter);
                            if (button_tmp->delay_button_node != WIDGET_BUTTON_DELAY_DISABLE)
                            {
                                button_tmp->delay_button_node = WIDGET_BUTTON_DELAY_ENABLE;
                            }
                        }
                        break;
                    }
                    counter++;
                }
                break;
            case MENU_BUTTON_PRESS:
                counter = 0;
                while (counter < hal_key_proc.hal_key_len)
                {
                    if (button_tmp->bind_key == hal_key_proc.hal_key_saved[counter] &&  hal_key_proc.hal_key_status[counter] == HAL_KEY_PRESS_STATUS)
                    {
                        if (button_tmp->delay_button_node == WIDGET_BUTTON_DELAY_ENABLE &&  button_tmp->delay_button_time != 0)
                        {
                            button_tmp->delay_button_node = get_time_counter() + button_tmp->delay_button_time;
                        }
                        if (button_tmp->delay_button_time != 0)
                        {
                            delay_tmp = get_time_counter();
                        }
                        if (delay_tmp >= button_tmp->delay_button_node)
                        {
                            button_tmp->menu_button_proc_fun();
                            update_key_value(counter);
                            if (button_tmp->delay_button_node != WIDGET_BUTTON_DELAY_DISABLE)
                            {
                                button_tmp->delay_button_node = WIDGET_BUTTON_DELAY_ENABLE;
                            }
                        }
                        break;
                    }
                    counter++;
                }
                break;
            default:
                break;
        }
    }
    //需要没有改变菜单的情况下，才继续显示该菜单的下个一个控件。
    if (cur_menu.menu_num == old_menu_num)
    {
        cur_menu.cur_dis_widget_num++;
        if ((cur_menu.cur_dis_widget_num -  menu_widget_index.menu_table_index[cur_menu.menu_num]) == cur_menu.menu_widget_len)
        {
            //  将控件处理一遍后，静态文本就不会再处理了
            menu_flag.flag.static_txt_displayed = 1;
            // 所有动态显示控件显示一次，才关闭动态显示，因为是用一个时间来控制的
            menu_flag.flag.display_txt_displayed = 1;
            cur_menu.cur_dis_widget_num =  menu_widget_index.menu_table_index[cur_menu.menu_num];
        }
    } else
    {
        old_menu_num = cur_menu.menu_num;
    }
}
uint8 i = 0;
void menu_inner_process(void)
{
    if (inner_proc_var[cur_menu.menu_num].inner_proc_type != INNER_UNKNOWN && inner_proc_var[cur_menu.menu_num].inner_proc_time != 0)
    {
        switch (inner_proc_var[cur_menu.menu_num].inner_proc_type)
        {
            case LOOP_OPERA :
                apply4delay(MENU_INNER_DELAY_FLAG, inner_proc_var[cur_menu.menu_num].inner_proc_time);
                if (get_delay_flag(MENU_INNER_DELAY_FLAG))
                {
                    *inner_proc_var[cur_menu.menu_num].inner_proc_value = inner_proc_var[cur_menu.menu_num].inner_proc_fun();
                }
                break;
            case OVERTIME_OPERA:
                apply4delay(MENU_INNER_DELAY_FLAG, inner_proc_var[cur_menu.menu_num].inner_proc_time);
                if (get_delay_flag(MENU_INNER_DELAY_FLAG))
                {
                    change_menu(inner_proc_var[cur_menu.menu_num].extend_var);
                }
                break;
            default:
                break;
        }
    }
}
static uint16 menu_get_widget_type(uint8 menu_widget_num)
{
    uint16 *widget_type_num;
    widget_type_num = (uint16 *)menu_widget_table.menu_table[menu_widget_num];
    return (*widget_type_num);
}
void register_ctrllable_table(uint8 widget_id)
{
    if (menu_controllable.controllable_widget_len < (CONTROLLABLE_WIDGET_MAX_LEN * 8) && (widget_id < (CONTROLLABLE_WIDGET_MAX_LEN * 8)))
    {
        menu_controllable.menu_controllabe_table[widget_id / 8] |= (1 << (widget_id % 8));
        menu_controllable.controllable_widget_len++;
    }
}
void set_ctrllable_widget_pointer(uint8 widget_id)
{
    if (widget_id != GET_CTRLLABLE_WRONG)
    {
        menu_controllable.menu_controllable_pointer = widget_id;
    }
}
uint8  get_ctrllable_widget_pointer(void)
{
    return (menu_controllable.menu_controllable_pointer);
}
uint8  get_ctrllable_right_edge(void)
{
    return (menu_controllable.right_edge);
}
uint8  get_ctrllable_left_edge(void)
{
    return (menu_controllable.left_edge);
}
uint16 get_ctrllable_widget_var_value(uint8 menu_changing_widget_num)
{
    display_text_widget_struct *display_txt;
    uint8 menu_proc_type;
    uint8 menu_seg_proc_type;
    uint16 menu_widget_type;
    uint16 menu_widget_value = 0xFFFF;
    if (menu_controllable.left_edge <= menu_changing_widget_num && menu_controllable.right_edge >=  menu_changing_widget_num)
    {
        menu_widget_type = menu_get_widget_type(menu_changing_widget_num);
        menu_proc_type = (menu_widget_type)&0x01;
        menu_seg_proc_type = (menu_widget_type >> 8) & 0x3;
        if (menu_proc_type == WIDGET_TEXT && menu_seg_proc_type != STATIC_TEXT)
        {
            switch (menu_seg_proc_type)
            {
                case SHIFT_TEXT:
                    break;
                case DAS_TEXT:
                    break;
                case DISPLAY_TEXT:
                    display_txt =  (display_text_widget_struct *)menu_widget_table.menu_table[menu_changing_widget_num];
                    menu_widget_value = display_txt->dis_var;
                    break;
                default:
                    break;
            }
        }
    }
    return (menu_widget_value);
}
void set_ctrllable_widget_var_value(uint8 menu_changing_widget_num, uint16 widget_value)
{
    display_text_widget_struct *display_txt;
    uint8 menu_proc_type;
    uint8 menu_seg_proc_type;
    uint16 menu_widget_type;
    if (menu_controllable.left_edge <= menu_changing_widget_num && menu_controllable.right_edge >=  menu_changing_widget_num)
    {
        menu_widget_type = menu_get_widget_type(menu_changing_widget_num);
        menu_proc_type = (menu_widget_type)&0x01;
        menu_seg_proc_type = (menu_widget_type >> 8) & 0x3;
        if (menu_proc_type == WIDGET_TEXT && menu_seg_proc_type != STATIC_TEXT)
        {
            switch (menu_seg_proc_type)
            {
                case SHIFT_TEXT:
                    break;
                case DAS_TEXT:
                    break;
                case DISPLAY_TEXT:
                    display_txt =  (display_text_widget_struct *)menu_widget_table.menu_table[menu_changing_widget_num];
                    display_txt->dis_var = widget_value;
                    break;
                default:
                    break;
            }
        }
    }
}
void set_ctrllable_widget_txt_value(uint8 menu_changing_widget_num, const uint8 *txt_value)
{
    display_text_widget_struct *display_txt;
    uint8 menu_proc_type;
    uint8 menu_seg_proc_type;
    uint16 menu_widget_type;
    if (menu_controllable.left_edge <= menu_changing_widget_num && menu_controllable.right_edge >=  menu_changing_widget_num)
    {
        menu_widget_type = menu_get_widget_type(menu_changing_widget_num);
        menu_proc_type = (menu_widget_type)&0x01;
        menu_seg_proc_type = (menu_widget_type >> 8) & 0x3;
        if (menu_proc_type == WIDGET_TEXT && menu_seg_proc_type != STATIC_TEXT)
        {
            switch (menu_seg_proc_type)
            {
                case SHIFT_TEXT:
                    break;
                case DAS_TEXT:
                    break;
                case DISPLAY_TEXT:
                    display_txt =  (display_text_widget_struct *)menu_widget_table.menu_table[menu_changing_widget_num];
                    display_txt->dis_txt = (__far uint8 *)txt_value;
                    break;
                default:
                    break;
            }
        }
    }
}
void ctrllable_widget_var_up(uint8 menu_changing_widget_num, uint8 max_value)
{
    display_text_widget_struct *display_txt;
    uint8 menu_proc_type;
    uint8 menu_seg_proc_type;
    uint16 menu_widget_type;
    if (menu_controllable.left_edge <= menu_changing_widget_num && menu_controllable.right_edge >=  menu_changing_widget_num)
    {
        menu_widget_type = menu_get_widget_type(menu_changing_widget_num);
        menu_proc_type = (menu_widget_type)&0x01;
        menu_seg_proc_type = (menu_widget_type >> 8) & 0x3;
        if (menu_proc_type == WIDGET_TEXT && menu_seg_proc_type != STATIC_TEXT)
        {
            switch (menu_seg_proc_type)
            {
                case SHIFT_TEXT:
                    break;
                case DAS_TEXT:
                    break;
                case DISPLAY_TEXT:
                    display_txt =  (display_text_widget_struct *)menu_widget_table.menu_table[menu_changing_widget_num];
                    display_txt->dis_var++;
                    display_txt->dis_var %= max_value;
                    break;
                default:
                    break;
            }
        }
    }
}
void ctrllable_widget_var_down(uint8 menu_changing_widget_num, uint8 max_value)
{
    display_text_widget_struct *display_txt;
    uint8 menu_proc_type;
    uint8 menu_seg_proc_type;
    uint16 menu_widget_type;
    if (menu_controllable.left_edge <= menu_changing_widget_num && menu_controllable.right_edge >=  menu_changing_widget_num)
    {
        menu_widget_type = menu_get_widget_type(menu_changing_widget_num);
        menu_proc_type = (menu_widget_type)&0x01;
        menu_seg_proc_type = (menu_widget_type >> 8) & 0x3;
        if (menu_proc_type == WIDGET_TEXT && menu_seg_proc_type != STATIC_TEXT)
        {
            switch (menu_seg_proc_type)
            {
                case SHIFT_TEXT:
                    break;
                case DAS_TEXT:
                    break;
                case DISPLAY_TEXT:
                    display_txt =  (display_text_widget_struct *)menu_widget_table.menu_table[menu_changing_widget_num];
                    if (display_txt->dis_var == 0)
                    {
                        display_txt->dis_var = max_value;
                    }
                    display_txt->dis_var--;
                    break;
                default:
                    break;
            }
        }
    }
}
void clr_ctrllable_widget_flash(uint8 menu_changing_widget_num)
{
    display_text_widget_struct *display_txt;
    uint8 menu_proc_type;
    uint8 menu_seg_proc_type;
    uint16 menu_widget_type;
    if (menu_controllable.left_edge <= menu_changing_widget_num && menu_controllable.right_edge >=  menu_changing_widget_num)
    {
        menu_widget_type = menu_get_widget_type(menu_changing_widget_num);
        menu_proc_type = (menu_widget_type)&0x01;
        menu_seg_proc_type = (menu_widget_type >> 8) & 0x3;
        if (menu_proc_type == WIDGET_TEXT && menu_seg_proc_type != STATIC_TEXT)
        {
            switch (menu_seg_proc_type)
            {
                case SHIFT_TEXT:
                    break;
                case DAS_TEXT:
                    break;
                case DISPLAY_TEXT:
                    display_txt =  (display_text_widget_struct *)menu_widget_table.menu_table[menu_changing_widget_num];
                    display_txt->flash_enable = 0;
                    display_txt->display_clr_flag = 0;
                    break;
                default:
                    break;
            }
        }
    }
}
void set_ctrllable_widget_flash(uint8 menu_changing_widget_num)
{
    display_text_widget_struct *display_txt;
    uint8 menu_proc_type;
    uint8 menu_seg_proc_type;
    uint16 menu_widget_type;
    if (menu_controllable.left_edge <= menu_changing_widget_num && menu_controllable.right_edge >=  menu_changing_widget_num)
    {
        menu_widget_type = menu_get_widget_type(menu_changing_widget_num);
        menu_proc_type = (menu_widget_type)&0x01;
        menu_seg_proc_type = (menu_widget_type >> 8) & 0x3;
        if (menu_proc_type == WIDGET_TEXT && menu_seg_proc_type != STATIC_TEXT)
        {
            switch (menu_seg_proc_type)
            {
                case SHIFT_TEXT:
                    break;
                case DAS_TEXT:
                    break;
                case DISPLAY_TEXT:
                    display_txt =  (display_text_widget_struct *)menu_widget_table.menu_table[menu_changing_widget_num];
                    display_txt->flash_enable = 1;
                    break;
                default:
                    break;
            }
        }
    }
}
uint8 get_left_ctrllable_widget(void)
{
    uint8 widget_id;
    widget_id = menu_controllable.menu_controllable_pointer;
    if (menu_controllable.left_edge != GET_CTRLLABLE_WRONG && menu_controllable.right_edge != GET_CTRLLABLE_WRONG)
    {
        if (widget_id == menu_controllable.left_edge)
        {
            widget_id = menu_controllable.right_edge + 1;
        }
        while (widget_id >  menu_controllable.left_edge)
        {
            widget_id--;
            if ((menu_controllable.menu_controllabe_table[widget_id / 8] & (1 << (widget_id % 8))) != 0)
            {
                break;
            }
        }
        return (widget_id);
    } else
    {
        return (GET_CTRLLABLE_WRONG);
    }
}
uint8 get_right_ctrllable_widget(void)
{
    uint8 widget_id;
    widget_id = menu_controllable.menu_controllable_pointer;
    if (menu_controllable.left_edge != GET_CTRLLABLE_WRONG && menu_controllable.right_edge != GET_CTRLLABLE_WRONG)
    {
        if (widget_id == menu_controllable.right_edge)
        {
            widget_id = menu_controllable.left_edge - 1;
        }
        while (widget_id <  menu_controllable.right_edge)
        {
            widget_id++;
            if ((menu_controllable.menu_controllabe_table[widget_id / 8] & (1 << (widget_id % 8))) != 0)
            {
                break;
            }
        }
        return (widget_id);
    } else
    {
        return (GET_CTRLLABLE_WRONG);
    }
}
void get_ctrllable_table_range(void)
{
    uint8 i = cur_menu.menu_widget_len;
    //这个菜单的最高地址
    uint8 high_location = menu_widget_index.menu_table_index[cur_menu.menu_num] + cur_menu.menu_widget_len - 1;
    //这个菜单的最低地址
    uint8 low_location = menu_widget_index.menu_table_index[cur_menu.menu_num];
    //求出可控表的右边缘
    while (i > 0)
    {
        if ((menu_controllable.menu_controllabe_table[high_location / 8] & (1 << (high_location % 8))) != 0)
        {
            menu_controllable.right_edge = high_location;
            break;
        }
        high_location--;
        i--;
    }
    if (i == 0)
    {
        menu_controllable.right_edge = GET_CTRLLABLE_WRONG;
    }
    i = 0;
    //求出可控表的左边缘
    while (i <  cur_menu.menu_widget_len)
    {
        if ((menu_controllable.menu_controllabe_table[low_location / 8] & (1 << (low_location % 8))) != 0)
        {
            menu_controllable.left_edge = low_location;
            break;
        }
        i++;
        low_location++;
    }
    if (i == cur_menu.menu_widget_len)
    {
        menu_controllable.left_edge = GET_CTRLLABLE_WRONG;
    }
}
void change_menu(uint8 menu_id)
{
    clr_delay_flag(MENU_INNER_DELAY_FLAG);
    clr_delay_flag(MENU_FLASH_FLAG);
    clr_ctrllable_widget_flash(get_ctrllable_widget_pointer());
    clr_unuse_key_value();
    hal_screen_clr();
    pre_menu.menu_num = cur_menu.menu_num;
    old_menu_num = cur_menu.menu_num;
    cur_menu.menu_num = menu_id;
    pre_menu.cur_dis_widget_num = cur_menu.cur_dis_widget_num;
    cur_menu.cur_dis_widget_num = menu_widget_index.menu_table_index[cur_menu.menu_num];
    pre_menu.menu_widget_len = cur_menu.menu_widget_len;
    if (cur_menu.menu_num < (MENU_MAX_COUNT - 1) && (cur_menu.menu_num < (menu_widget_index.menu_count - 1)))
    {
        cur_menu.menu_widget_len = menu_widget_index.menu_table_index[cur_menu.menu_num + 1] - menu_widget_index.menu_table_index[cur_menu.menu_num];
    } else if ((cur_menu.menu_num == (MENU_MAX_COUNT - 1)) || (cur_menu.menu_num == (menu_widget_index.menu_count - 1)))
    {
        cur_menu.menu_widget_len = menu_widget_table.menu_widget_count - menu_widget_index.menu_table_index[cur_menu.menu_num];
    }
    menu_flag.flag.static_txt_displayed = 0;
    get_ctrllable_table_range();
    set_ctrllable_widget_pointer(menu_controllable.right_edge);
    set_ctrllable_widget_flash(get_ctrllable_widget_pointer());
}
#endif
